package com.qidian.mes.util.interceptor;

import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.qidian.mes.util.Constant;
import com.qidian.mes.util.JSONTools;
import com.qidian.mes.util.jwt.JWTUtil;
import com.qidian.mes.util.pojo.MESResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author 戴着假发的程序员
 * @Company 起点编程
 * @Time 2023/11/3 10:31
 * @Description
 */
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    private JWTUtil jwtUtil;

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 设置跨域处理
        response.setHeader("Access-Control-Allow-Origin", "*"); // 设置允许所有跨域访问
        response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE");
        response.setHeader("Access-Control-Max-Age", "1800");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        // 进入请求之前校验登陆状态
        // 从请求头中获取token
        String token = request.getHeader("token");
        if(token != null && !token.equals("")){
            try {
                jwtUtil.checkToken(token);
                return true;// 校验通过
            } catch (TokenExpiredException e){
                System.out.println("token过期");
                // 检查这个token是否在redis中
                if(redisTemplate.hasKey(token)){
                    //redisTemplate.delete(token);// 删除原来的token
                    // token续签
                    // 从redis中获取出之前存储的信息
                    String infoStr = redisTemplate.opsForValue().get(token);
                    redisTemplate.delete(token);// 删除原来的token
                    // 将infoStr转换为map
                    Map<String,String> map = JSONTools.json2object(infoStr,HashMap.class);
                    // 重新生成token
                    token = jwtUtil.getToken(map);
                    // 将token放入redis, 使用token作为key
                    redisTemplate.opsForValue().set(token,infoStr);
                    // 设置时间为两小时
                    redisTemplate.expire(token,2, TimeUnit.HOURS);
                    // 给客户端响应续签状态
                    MESResult result = new MESResult(Constant.STAUS_LOGIN_RENEWAL,token,null);
                    response.setContentType("application/json;charset=utf-8");
                    response.getWriter().write(JSONTools.object2json(result));
                    return false;
                }
            }catch (Exception e) {
                System.out.println("token校验失败");
            }
        }
        // 给客户端响应未登陆状态
        MESResult result = new MESResult(Constant.STATUS_NO_LOGIN,"未登录状态",null);
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(JSONTools.object2json(result));
        return false;// 拦截
    }
}
